package com.xxkfz.simplememory.controller;

import cn.dev33.satoken.stp.SaTokenInfo;
import cn.dev33.satoken.stp.StpUtil;
import cn.dev33.satoken.util.SaResult;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;


/**
 * @program: xxkfz-sa-token
 * @ClassName UserController.java
 * @author: xxkfz
 * @create: 2023-11-07 15:06
 * @description: 用户登录、注销、会话查询演示
 * @Version 1.0
 **/
@RestController
@RequestMapping("/user/")
@Slf4j
public class UserController {

    /**
     * 登录:  http://localhost:8089/user/doLogin?username=xxkfz&password=123456
     *
     * @param username
     * @param password
     * @return
     */
    @RequestMapping("doLogin")
    public SaResult doLogin(String username, String password) {
        // 此处仅作模拟示例，真实项目需要从数据库中查询数据进行比对
        if ("xxkfz".equals(username) && "123456".equals(password)) {
            StpUtil.login(10001);
            return SaResult.ok("登录成功");
        }
        return SaResult.error("登录失败");
    }

    /**
     * 获取当前会话是否已经登录  返回true=已登录，false=未登录
     * http://localhost:8089/user/
     *
     * @return
     */
    @RequestMapping("isLogin")
    public String isLogin() {
        return "当前会话是否登录：" + StpUtil.isLogin();
    }

    /**
     * 检查当前会话是否已经登录 如果未登录，则抛出异常：`NotLoginException`
     *
     * @returnn
     */
    @GetMapping("checkLogin")
    public String checkLogin() {
        StpUtil.checkLogin();
        return "";
    }

    /**
     * 当前会话注销登录
     *
     * @return
     */
    @GetMapping("logout")
    public String logout() {
        StpUtil.logout();
        return "已注销";
    }

    /**
     * 获取当前会话账号id, 如果未登录，则抛出异常：`NotLoginException`
     *
     * @return
     */
    @GetMapping("getLoginId")
    public String getLoginId() {
        Object loginId = StpUtil.getLoginId();
        String loginIdAsString = StpUtil.getLoginIdAsString();// 获取当前会话账号id, 并转化为`String`类型
        int loginIdAsInt = StpUtil.getLoginIdAsInt();// 获取当前会话账号id, 并转化为`int`类型
        long loginIdAsLong = StpUtil.getLoginIdAsLong();// 获取当前会话账号id, 并转化为`long`类型
        String loginIdAsDefault = StpUtil.getLoginId("未登录"); //  获取当前会话账号id, 如果未登录，则返回默认值 （`defaultValue`可以为任意类型）
        log.error("当前会话账号id = {}", loginIdAsString);
        log.error("当前会话账号id = {}", loginIdAsInt);
        log.error("当前会话账号id = {}", loginIdAsLong);
        log.error("当前会话账号id = {}", loginIdAsDefault);
        return "当前会话账号id: " + loginId.toString();
    }

    /**
     * 查询Token信息
     *
     * @return
     */
    @RequestMapping("tokenInfo")
    public SaResult tokenInfo() {
        // TokenName 是 Token 名称的意思，此值也决定了前端提交 Token 时应该使用的参数名称
        String tokenName = StpUtil.getTokenName();
        System.out.println("前端提交 Token 时应该使用的参数名称：" + tokenName);

        // 使用 StpUtil.getTokenValue() 获取前端提交的 Token 值
        // 框架默认前端可以从以下三个途径中提交 Token：
        // 		Cookie 		（浏览器自动提交）
        // 		Header头	（代码手动提交）
        // 		Query 参数	（代码手动提交） 例如： /user/getInfo?satoken=xxxx-xxxx-xxxx-xxxx
        // 读取顺序为： Query 参数 --> Header头 -- > Cookie
        // 以上三个地方都读取不到 Token 信息的话，则视为前端没有提交 Token
        String tokenValue = StpUtil.getTokenValue();
        System.out.println("前端提交的Token值为：" + tokenValue);

        // TokenInfo 包含了此 Token 的大多数信息
        SaTokenInfo info = StpUtil.getTokenInfo();
        System.out.println("Token 名称：" + info.getTokenName());
        System.out.println("Token 值：" + info.getTokenValue());
        System.out.println("当前是否登录：" + info.getIsLogin());
        System.out.println("当前登录的账号id：" + info.getLoginId());
        System.out.println("当前登录账号的类型：" + info.getLoginType());
        System.out.println("当前登录客户端的设备类型：" + info.getLoginDevice());
        System.out.println("当前 Token 的剩余有效期：" + info.getTokenTimeout()); // 单位：秒，-1代表永久有效，-2代表值不存在
        System.out.println("当前 Token 距离被冻结还剩：" + info.getTokenActiveTimeout()); // 单位：秒，-1代表永久有效，-2代表值不存在
        System.out.println("当前 Account-Session 的剩余有效期" + info.getSessionTimeout()); // 单位：秒，-1代表永久有效，-2代表值不存在
        System.out.println("当前 Token-Session 的剩余有效期" + info.getTokenSessionTimeout()); // 单位：秒，-1代表永久有效，-2代表值不存在

        // 返回给前端
        return SaResult.data(StpUtil.getTokenInfo());
    }

}
